"""
This file is part of GSBEdit. For copyright and licensing information, please
see gsbedit.py in the GSBEdit base directory.
"""


import wx
import ui_elements.controls.textctrlborder as tcb
import ui_elements.controls.comboboxborder as cbb


class InfoPanel(wx.Panel):
    def __init__(self, parent, attr_group):
        wx.Panel.__init__(self, parent, -1)
        self.attr_group = attr_group
        self.callbacks = self.attr_group.callbacks
        
        self.keys = {}
    
    
    def group_callback(self, event, params):
        if event in self.callbacks:
            self.callbacks[event](*params)
    
    
    def set_module(self, module, module_config):
        self.module = module
        self.module_config = module_config
        
        self.group_callback('module_change_pre', (module, module_config))
        self.generate_content()
        self.group_callback('module_change_post', (module, module_config))
    
    
    def get_subpanel_attr(self):
        return self.attr_group.get_subpanel_attr(self.module_config)
    
    
    def generate_content(self):
        content = wx.BoxSizer(wx.HORIZONTAL)
        ctrl_list = []
        subpanel_attr = self.get_subpanel_attr()
        
        for attr_list in subpanel_attr['items']:
            this_content = wx.BoxSizer(wx.VERTICAL)
            captions = []
            
            for item in attr_list:
                item_id = item.get('id', -1)
                valmod = item.get('valmod', str)
                rvalmod = item.get('rvalmod', str)
                
                if item['type'] == 'caption':
                    ctrl = wx.TextCtrl(self, item_id, item['text'], style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_BESTWRAP | wx.BORDER_NONE)
                    this_content.Add(ctrl, 1, wx.EXPAND)
                    this_content.Add((1, 10), 0)
                elif item['type'] == 'static_text':
                    ctrl = wx.StaticText(self, -1, item['text'])
                    this_content.Add(ctrl, 0, wx.EXPAND)
                    this_content.Add((1, 10), 0)
                    if 'key' in item: ctrl_list.append((item['key'], ctrl))
                elif item['type'] == 'spacer':
                    this_content.Add((0, 0), 1, wx.EXPAND)
                else:
                    if not(item['key'] in self.module_config['required'] or item['key'] in self.module_config['optional']):
                        continue

                    text = wx.StaticText(self, -1, '%s:' % item['desc'])
                    
                    if item['type'] == 'text':
                        ctrl = tcb.TextCtrlBorder(self, item_id)
                        horz = self.make_horz_ctrl(text, ctrl)
                    elif item['type'] == 'big_text':
                        ctrl = tcb.TextCtrlBorder(self, item_id, style=wx.TE_MULTILINE|wx.TE_NOHIDESEL, size=(-1,80))
                        horz = self.make_horz_ctrl(text, ctrl, wx.ALIGN_TOP)
                    elif item['type'] == 'choice_drop':
                        ctrl = cbb.ComboBoxBorder(self, item_id, choices=item['options'], style=wx.CB_READONLY)
                        horz = self.make_horz_ctrl(text, ctrl)
                    elif item['type'] == 'checkbox':
                        #ctrl = wx.CheckBox(self, item_id, item['desc'])
                        #horz = ctrl
                        ctrl = cbb.ComboBoxBorder(self, item_id, choices=['', 'Yes', 'No'], style=wx.CB_READONLY)
                        horz = self.make_horz_ctrl(text, ctrl)
                        valmod = self.convert_checkbox_value
                        rvalmod = self.rconvert_checkbox_value
                    
                    if item['key'] in self.module_config['required']:
                        ctrl.SetBackgroundColour("#CDCD00")
                    
                    if 'tip' in item:
                        ctrl.SetToolTipString(item['tip'])
                    
                    this_content.Add(horz, 0, wx.EXPAND)
                    captions.append(text)

                    if 'key' in item: self.register_key(ctrl, item['key'], item['type'], valmod, rvalmod)
                    ctrl_list.append((item['key'], ctrl))
            
            if len(captions) == 0: continue
            mins = [caption.GetBestSize()[0] for caption in captions]
            if len(mins) > 0:
                maximum_x = max(mins)
                for caption in captions:
                    caption.SetInitialSize(wx.Size(maximum_x, -1))
            
            content.Add(this_content, 1, wx.EXPAND)
        
        self.update_orig_vals()
        self.populate_values(self.orig_vals)

        top_level = wx.BoxSizer(wx.VERTICAL)
        top_level.Add(content, 1, wx.EXPAND | wx.ALL, 10)
        self.SetSizer(top_level)
        
        for b in self.attr_group.bindings:
            self.Bind(b['event'], b['func'], id=b['id'])
        
        self.attr_group.set_controls(dict(ctrl_list))


    def make_horz_ctrl(self, text, ctrl, text_align=wx.ALIGN_CENTER):
        horz = wx.BoxSizer(wx.HORIZONTAL)
        horz.Add(text, 0, text_align | wx.ALL, 5)
        horz.Add(ctrl, 1, wx.EXPAND | wx.ALIGN_BOTTOM | wx.ALL, 5)
        return horz
    
    
    def register_key(self, control, key, ctrl_type, valmod=str, rvalmod=str):
        self.keys[key] = (control, ctrl_type, valmod, rvalmod)
    
    
    def populate_values(self, values):
        for key,(control,ctrl_type,valmod,rvalmod) in self.keys.iteritems():
            if key in values:
                value = valmod(values[key])
                if ctrl_type in ['text', 'big_text', 'choice_drop', 'checkbox']:
                    control.SetValue(value)
                #elif ctrl_type in ['checkbox']:
                #    control.SetValue(bool(value))
                else:
                    print "Unknown control type: %s" % ctrl_type
    
    
    def update_orig_vals(self):
        self.orig_vals = self.module.get_values('config')
    
    
    def has_edits(self):
        for key,(control,ctrl_type,valmod,rvalmod) in self.keys.iteritems():
            if key in self.orig_vals:
                orig_val = self.orig_vals[key]
                new_val = control.GetValue()
                new_val = rvalmod(new_val)
                
                # User has removed the option when it used to exist
                if new_val in [None, '']:
                    print '%s changed: "%s" => [Removed]' % (key, orig_val)
                    return True

                # User has edited the option
                if new_val != orig_val:
                    print '%s changed: "%s" => "%s"' % (key, orig_val, new_val)
                    return True
            else:
                new_val = control.GetValue()
                new_val = rvalmod(new_val)
                
                if not(new_val in [None, '']):
                    print '%s changed: [Not present] => "%s"' % (key, new_val)
                    return True
        return False
        

    def get_edits(self):
        edits =  []
        
        for key,(control,ctrl_type,valmod,rvalmod) in self.keys.iteritems():
            if key in self.orig_vals:
                orig_val = self.orig_vals[key]
                new_val = control.GetValue()
                new_val = rvalmod(new_val)
                
                # User has removed the option when it used to exist
                if new_val in [None, '']:
                    edits.append((key, new_val))

                # User has edited the option
                elif new_val != orig_val:
                    edits.append((key, new_val))
            else:
                new_val = control.GetValue()
                new_val = rvalmod(new_val)
                
                if not(new_val in [None, '']):
                    edits.append((key, new_val))
                    
        return edits
    
    
    def should_display(self):
        for item_list in self.content_desc:
            for item in item_list:
                if not('key' in item): continue
                if item['key'] in self.module_config['required'] or item['key'] in self.module_config['optional']:
                    return True
        return False
    
    
    def convert_checkbox_value(self, value):
        if value == '0': return 'No'
        if value == '1': return 'Yes'
        return ''
    
    
    def rconvert_checkbox_value(self, value):
        if value == 'No': return '0'
        if value == 'Yes': return '1'
        return None
    
    
    def prepare_for_display(self):
        self.set_content(self.content_desc)
